Skip to content

feat(FR-2744): restore Vitest coverage reporting in CI#7065

Merged
graphite-app[bot] merged 1 commit intomainfrom
04-27-feat_fr-2744_restore_vitest_coverage_reporting_in_ci
Apr 30, 2026
Merged

feat(FR-2744): restore Vitest coverage reporting in CI#7065
graphite-app[bot] merged 1 commit intomainfrom
04-27-feat_fr-2744_restore_vitest_coverage_reporting_in_ci

Conversation

@nowgnuesLee
Copy link
Copy Markdown
Contributor

@nowgnuesLee nowgnuesLee commented Apr 27, 2026

Resolves #7064(FR-2744)

Summary

FR-2611 dropped ArtiomTr/jest-coverage-report-action (Jest-only) when CI moved to Vitest, so PRs lost the coverage diff comment and inline test-failure annotations. This restores the equivalent surface using davelosert/vitest-coverage-report-action@v2.

Local setup

  • Add @vitest/coverage-v8@^4.1.4 as devDependency in react/, packages/backend.ai-ui/, root.
  • Coverage block in each vitest.config.ts:
    • provider: 'v8' — uses Node's V8 inspector, no Babel transform needed (fastest provider).
    • reporter: ['text', 'json', 'json-summary', 'html']json-summary is what the GitHub Action consumes; text keeps a console summary; html lets devs open coverage/index.html locally.
    • exclude patterns trim test files, stories, generated Relay artifacts, and zero-logic entries (src/index.tsx, reportWebVitals, BUI locale catalog, wsproxy, bundled backend.ai-client-node.*).
  • /coverage added to packages/backend.ai-ui/.gitignore (root and react/ already had it).

CI setup

  • .github/workflows/vitest.yml gains pull-requests: write permission so the action can post / update its PR comment.
  • Each of the three jobs (react-vitest, backend-ai-ui-vitest, root-vitest) runs pnpm exec vitest run --coverage and follows it with a davelosert/vitest-coverage-report-action@v2 step keyed by a unique name: so the three PR comments don't collide.
  • The action runs with if: always() so a coverage comment posts even when tests fail (matches the prior Jest behaviour, which surfaced failed-test annotations).

Verification

=== react/   ===  Lines 7.23%  (1645/22722)
=== BUI      ===  Lines 7.91%  (317/4006)
=== root     ===  Lines 3.66%  (282/7703)
  • All three workspaces produce coverage/coverage-summary.json in the shape the action expects
  • Test pass counts unchanged (react 856/856, BUI 315 + 5 skip, root 90 + 1 skip)
  • No regression in lint / format

Out of scope

  • No coverage threshold gates — baseline %s above are intentionally low (mostly UI code without unit tests). Gating now would block normal PRs. A separate decision on thresholds belongs to a follow-up after the team agrees on a target.
  • README coverage badge.
  • Backfilling the 6 TODO(FR-2609) skipped tests.

Stack

Top of the Vite migration stack (now 12 PRs). Builds on PR #6879 (fix(FR-2606) webpackIgnore → @vite-ignore).

Copy link
Copy Markdown
Contributor Author

nowgnuesLee commented Apr 27, 2026


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • flow:merge-queue - adds this PR to the back of the merge queue
  • flow:hotfix - for urgent changes, fast-track this PR to the front of the merge queue

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has required the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 27, 2026

Coverage Report for backend-ai-ui-coverage (./packages/backend.ai-ui)

Status Category Percentage Covered / Total
🔵 Lines 7.79% 317 / 4066
🔵 Statements 7.1% 363 / 5106
🔵 Functions 8.52% 86 / 1009
🔵 Branches 6.33% 318 / 5020
File CoverageNo changed files found.
Generated in workflow #110 for commit dd140f8 by the Vitest Coverage Report Action

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 27, 2026

Coverage Report for react-coverage (./react)

Status Category Percentage Covered / Total
🔵 Lines 7.24% 1646 / 22722
🔵 Statements 6.04% 1777 / 29374
🔵 Functions 5.69% 285 / 5007
🔵 Branches 4.38% 1169 / 26682
File CoverageNo changed files found.
Generated in workflow #5 for commit 4ee4407 by the Vitest Coverage Report Action

@nowgnuesLee nowgnuesLee force-pushed the 04-27-feat_fr-2744_restore_vitest_coverage_reporting_in_ci branch from 5e55ed5 to 4ee4407 Compare April 27, 2026 05:24
@github-actions github-actions Bot added size:M 30~100 LoC and removed size:L 100~500 LoC labels Apr 27, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 27, 2026

Coverage Report for root-coverage

Status Category Percentage Covered / Total
🔵 Lines 9.67% 235 / 2429
🔵 Statements 10.22% 256 / 2503
🔵 Functions 7.63% 29 / 380
🔵 Branches 11.5% 168 / 1460
File CoverageNo changed files found.
Generated in workflow #98 for commit 27c1b3a by the Vitest Coverage Report Action

@nowgnuesLee nowgnuesLee force-pushed the 04-27-feat_fr-2744_restore_vitest_coverage_reporting_in_ci branch from 4ee4407 to ce03855 Compare April 27, 2026 13:57
@nowgnuesLee nowgnuesLee force-pushed the 04-21-fix_fr-2606_replace_webpackignore_with_vite-ignore_in_dynamic_plugin_imports branch from 2b59a1b to 4147197 Compare April 27, 2026 13:57
@nowgnuesLee nowgnuesLee marked this pull request as ready for review April 28, 2026 04:25
Copilot AI review requested due to automatic review settings April 28, 2026 04:25
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Restores PR coverage diff reporting in CI after the migration from Jest to Vitest by enabling Vitest coverage generation (V8 provider) in each workspace and posting coverage summaries back to pull requests via a dedicated GitHub Action.

Changes:

  • Add @vitest/coverage-v8 devDependency to root, react/, and packages/backend.ai-ui/.
  • Configure consistent Vitest coverage reporting (json-summary, etc.) across root, React, and backend.ai-ui Vitest configs.
  • Update the Vitest CI workflow to run vitest --coverage per workspace and post PR coverage comments via davelosert/vitest-coverage-report-action@v2.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
vitest.config.ts Adds root-suite coverage configuration (V8 provider + json-summary output).
react/vitest.config.ts Adds React workspace coverage configuration and exclusions.
react/package.json Adds @vitest/coverage-v8 to enable coverage collection.
packages/backend.ai-ui/vitest.config.ts Adds backend.ai-ui workspace coverage configuration and exclusions.
packages/backend.ai-ui/package.json Adds @vitest/coverage-v8 to enable coverage collection.
packages/backend.ai-ui/.gitignore Ignores workspace coverage/ output.
package.json Adds @vitest/coverage-v8 at the root for root-suite coverage runs.
.github/workflows/vitest.yml Runs Vitest with coverage and posts PR coverage comments for each job/workspace.

Comment thread .github/workflows/vitest.yml
@nowgnuesLee nowgnuesLee force-pushed the 04-21-fix_fr-2606_replace_webpackignore_with_vite-ignore_in_dynamic_plugin_imports branch from 4147197 to f3317ab Compare April 28, 2026 05:02
@nowgnuesLee nowgnuesLee force-pushed the 04-27-feat_fr-2744_restore_vitest_coverage_reporting_in_ci branch from ce03855 to bbf0e01 Compare April 28, 2026 05:02
@nowgnuesLee nowgnuesLee force-pushed the 04-21-fix_fr-2606_replace_webpackignore_with_vite-ignore_in_dynamic_plugin_imports branch from f3317ab to 91d8e0d Compare April 28, 2026 05:15
@nowgnuesLee nowgnuesLee force-pushed the 04-27-feat_fr-2744_restore_vitest_coverage_reporting_in_ci branch 2 times, most recently from 7892855 to be9870b Compare April 28, 2026 05:19
@nowgnuesLee nowgnuesLee force-pushed the 04-21-fix_fr-2606_replace_webpackignore_with_vite-ignore_in_dynamic_plugin_imports branch 2 times, most recently from 7223909 to ac5909d Compare April 28, 2026 05:25
@nowgnuesLee nowgnuesLee force-pushed the 04-27-feat_fr-2744_restore_vitest_coverage_reporting_in_ci branch from be9870b to 8979590 Compare April 28, 2026 05:25
@nowgnuesLee nowgnuesLee force-pushed the 04-21-fix_fr-2606_replace_webpackignore_with_vite-ignore_in_dynamic_plugin_imports branch from ac5909d to 0d2caed Compare April 28, 2026 05:28
@nowgnuesLee nowgnuesLee force-pushed the 04-27-feat_fr-2744_restore_vitest_coverage_reporting_in_ci branch from 8979590 to 1719229 Compare April 28, 2026 05:28
@yomybaby yomybaby force-pushed the 04-21-fix_fr-2606_replace_webpackignore_with_vite-ignore_in_dynamic_plugin_imports branch from 0d2caed to a4205c8 Compare April 30, 2026 12:08
@yomybaby yomybaby force-pushed the 04-27-feat_fr-2744_restore_vitest_coverage_reporting_in_ci branch from 1719229 to 27c1b3a Compare April 30, 2026 12:08
@graphite-app
Copy link
Copy Markdown

graphite-app Bot commented Apr 30, 2026

Merge activity

Resolves #7064(FR-2744)

## Summary

FR-2611 dropped `ArtiomTr/jest-coverage-report-action` (Jest-only) when CI moved to Vitest, so PRs lost the coverage diff comment and inline test-failure annotations. This restores the equivalent surface using `davelosert/vitest-coverage-report-action@v2`.

### Local setup
- Add `@vitest/coverage-v8@^4.1.4` as devDependency in `react/`, `packages/backend.ai-ui/`, root.
- Coverage block in each `vitest.config.ts`:
  - `provider: 'v8'` — uses Node's V8 inspector, no Babel transform needed (fastest provider).
  - `reporter: ['text', 'json', 'json-summary', 'html']` — `json-summary` is what the GitHub Action consumes; `text` keeps a console summary; `html` lets devs open `coverage/index.html` locally.
  - `exclude` patterns trim test files, stories, generated Relay artifacts, and zero-logic entries (`src/index.tsx`, `reportWebVitals`, BUI locale catalog, `wsproxy`, bundled `backend.ai-client-node.*`).
- `/coverage` added to `packages/backend.ai-ui/.gitignore` (root and react/ already had it).

### CI setup
- `.github/workflows/vitest.yml` gains `pull-requests: write` permission so the action can post / update its PR comment.
- Each of the three jobs (`react-vitest`, `backend-ai-ui-vitest`, `root-vitest`) runs `pnpm exec vitest run --coverage` and follows it with a `davelosert/vitest-coverage-report-action@v2` step keyed by a unique `name:` so the three PR comments don't collide.
- The action runs with `if: always()` so a coverage comment posts even when tests fail (matches the prior Jest behaviour, which surfaced failed-test annotations).

## Verification

```
=== react/   ===  Lines 7.23%  (1645/22722)
=== BUI      ===  Lines 7.91%  (317/4006)
=== root     ===  Lines 3.66%  (282/7703)
```

- [x] All three workspaces produce `coverage/coverage-summary.json` in the shape the action expects
- [x] Test pass counts unchanged (react 856/856, BUI 315 + 5 skip, root 90 + 1 skip)
- [x] No regression in lint / format

## Out of scope

- **No coverage threshold gates** — baseline %s above are intentionally low (mostly UI code without unit tests). Gating now would block normal PRs. A separate decision on thresholds belongs to a follow-up after the team agrees on a target.
- README coverage badge.
- Backfilling the 6 `TODO(FR-2609)` skipped tests.

## Stack

Top of the Vite migration stack (now 12 PRs). Builds on PR #6879 (`fix(FR-2606)` webpackIgnore → @vite-ignore).
@graphite-app graphite-app Bot force-pushed the 04-21-fix_fr-2606_replace_webpackignore_with_vite-ignore_in_dynamic_plugin_imports branch from a4205c8 to c303197 Compare April 30, 2026 12:18
@graphite-app graphite-app Bot force-pushed the 04-27-feat_fr-2744_restore_vitest_coverage_reporting_in_ci branch from 27c1b3a to dd140f8 Compare April 30, 2026 12:19
graphite-app Bot pushed a commit that referenced this pull request Apr 30, 2026
Resolves #7070(FR-2746)

## Summary

During FR-2609 + the BUI/root follow-up, 5 tests were skipped with `TODO(FR-2609)` markers because of two distinct compatibility issues. Both are now resolved.

### Group A — `@rc-component/motion` + jsdom 29 (4 tests)

- `packages/backend.ai-ui/src/components/BAIButton.test.tsx` (2 tests asserting the loading icon clears after async action completion)
- `packages/backend.ai-ui/src/components/BAIUnmountAfterClose.test.tsx` (2 tests asserting the Modal unmounts after the close animation finishes)

**Root cause**: antd v6 uses `@rc-component/motion` (CSSMotion) for Button loading-icon and Modal close transitions. The package probes vendor-prefixed style props on a `div` at module init to compute a `supportTransition` flag. Jest's older jsdom did not expose those props → flag resolved to `false` → motion completed synchronously. jsdom 29 (Vitest) exposes them → flag is `true` → motion waits for a `transitionend` event that jsdom never fires.

**Fix**: a MutationObserver in `setupTests.ts` watches the document for class additions matching `*-(leave|enter|appear)-active`, then queues a microtask to dispatch a synthetic `transitionend` on the element. This emulates what a real browser does when the CSS transition completes — rc-motion's listener fires, the active class is removed, and the assertion sees the expected post-transition DOM.

This was chosen after `vi.mock('@rc-component/motion/es/util/motion', ...)` failed to intercept the package-internal relative import (`./util/motion`). The MutationObserver works regardless of how `supportTransition` resolves and is the most robust fix.

### Group B — CJS `require('fs')` not interceptable by `vi.mock` (1 test)

- `scripts/i18n-merge-driver.test.ts` (`should parse JSON from file correctly`)

**Root cause**: the driver is a CommonJS `.js` file invoked by git via `node scripts/i18n-merge-driver.js %O %A %B` (per `.git/config`). It must remain CJS. Its inline `require('fs')` slips past Vitest's module-mock transform, so `vi.mock('fs', ...)` did not propagate.

**Fix**: rewrite the test to use a real temp file via `fs.mkdtempSync`, torn down in `afterEach`. This bypasses the CJS-mock incompat by not mocking, while still validating the observable behavior — `readJSON` parses JSON correctly and throws on invalid input.

**Bonus catch**: the existing `should throw error for invalid JSON` test was actually testing missing-file `ENOENT` (the mock had been silently failing in that test too). It now correctly tests invalid JSON parsing as labelled.

### CI tweak — root testTimeout + cjs coverage exclude

The first CI run on this PR exposed two coverage-related issues that didn't surface locally:

- `scripts/gen-theme-schema.test.ts > generates a valid JSON schema file` — exercises antd's type tree several times. Locally completes in ~2s; under V8 coverage instrumentation on CI's smaller runners it routinely exceeds the default 5 s per-test timeout.
- After that test failed, the davelosert action couldn't post a coverage comment because the `coverage-summary.json` was generated late / partially.

Two small adjustments to `vitest.config.ts` (root) make CI match local behaviour:
- `testTimeout: 30000` — generous per-test budget that matches what coverage adds in CI.
- `coverage.exclude: 'scripts/**/*.cjs'` — build tooling (the gen-theme-schema generator, the i18n merge driver) is exercised by the tests but its coverage % is not actionable; excluding it removes the heaviest source of v8 instrumentation overhead in this suite.

These are bundled here because the failing CI run on this PR was the first surfaceing of the issue; both adjustments are tightly scoped to root coverage runs.

## Verification

```
before:
  react/   856 pass | 0  skip
  BUI      315 pass | 5  skip
  root      90 pass | 1  skip
  total   1261 pass | 6  skip

after:
  react/   856 pass | 0  skip
  BUI      319 pass | 1  skip   ← 4 newly passing (Group A)
  root      91 pass | 0  skip   ← 1 newly passing (Group B)
  total   1266 pass | 1  skip
```

The remaining 1 skip in BUI is `BAIDomainSelect.test.tsx` `describe.skip` from FR-1731 (pre-existing, unrelated to this migration).

Local `pnpm exec vitest run --coverage` now produces `coverage/coverage-summary.json` for the root suite without timing out.

## Out of scope

- Fixing the FR-1731 `BAIDomainSelect` skip (separate concern).
- A global motion-disable opt-out beyond the helper — the MutationObserver is sufficient and minimally invasive.

## Stack

Top of the Vite migration stack (now 13 PRs). Builds on PR #7065 (`feat(FR-2744)` Vitest coverage reporting).
Base automatically changed from 04-21-fix_fr-2606_replace_webpackignore_with_vite-ignore_in_dynamic_plugin_imports to main April 30, 2026 12:34
@graphite-app graphite-app Bot merged commit dd140f8 into main Apr 30, 2026
6 of 8 checks passed
@graphite-app graphite-app Bot deleted the 04-27-feat_fr-2744_restore_vitest_coverage_reporting_in_ci branch April 30, 2026 12:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30~100 LoC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Restore Vitest coverage reporting in CI

2 participants